package com.tomato.thread.pool;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import static java.text.MessageFormat.format;

public class CustomThreadFactory implements ThreadFactory {
    private ThreadGroup threadGroup;

    private AtomicLong threadNumber = new AtomicLong(1L);

    /**
     * 线程池中线程组名字前缀
     */
    private String prefix;

    public CustomThreadFactory() {
        this("");
    }

    public CustomThreadFactory(String prefixName) {
        SecurityManager securityManager = System.getSecurityManager();
        threadGroup = securityManager != null ? securityManager.getThreadGroup() : Thread.currentThread().getThreadGroup();
        prefix = (prefixName != null && !"".equals(prefixName)) ? prefixName : "tomato-pool-thread";
    }

    @Override
    public Thread newThread(Runnable r) {
        /**
         * 当设置stackSize属于<=0 时，以-Xss为准
         * 当设置stackSize属于(0, 4k]区间时，设置的-Xss会失效，栈空间取默认值1M
         * 当设置stackSize属于(4k, 64k]区间时，设置的-Xss会失效，栈空间取4k。
         * 当设置stackSize属于(64k, 128k]区间时，设置的-Xss会失效，栈空间取64k。
         * 当设置stackSize属于 >128k 时，设置的-Xss会失效，栈空间取stackSize本身
         */
        Thread thread = new Thread(threadGroup,r, prefix + "-" + threadNumber.getAndIncrement(), 0);

        if (thread.isDaemon()) {
            thread.setDaemon(false);
        }

        if (thread.getPriority() != Thread.NORM_PRIORITY) {
            thread.setPriority(Thread.NORM_PRIORITY);
        }

        return thread;
    }
}

class Test {
    public static final Integer ACPU = Runtime.getRuntime().availableProcessors();
    public static void main(String[] args) {
        ThreadPoolExecutor executor =
                new ThreadPoolExecutor(
                        ACPU * 2 + 1,
                        ACPU * 2 + 1,
                        0,
                        TimeUnit.SECONDS,
                        new LinkedBlockingDeque<>(600),
                        new CustomThreadFactory());

        for(int i = 1; i < 1_00; i++) {
            executor.execute(() -> {
                System.out.println(format("{0}执行任务完成",Thread.currentThread().getName()));
            });
        }
    }
}